{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nQ7xbeAhW56k"
   },
   "source": [
    "# Augmenting PostgreSQL with AI using EvaDB\n",
    "In this article, we illustrate how EvaDB seamlessly integrates AI into your PostgreSQL workflows for solving complex data manipulation tasks. In particular, we demonstrate how EvaDB enables AI-powered semantic join between tables that do not directly share a column that can be joined on."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OO_piYnb0c1k"
   },
   "source": [
    "<table align=\"left\">\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/georgia-tech-db/eva/blob/staging/tutorials/15-AI-powered-join.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" /> Run on Google Colab</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://github.com/georgia-tech-db/eva/blob/staging/tutorials/15-AI-powered-join.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" /> View source on GitHub</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://github.com/georgia-tech-db/eva/raw/staging/tutorials/15-AI-powered-join.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" /> Download notebook</a>\n",
    "  </td>\n",
    "</table><br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "u4duS22nW56m"
   },
   "source": [
    "## Challenge: \"AI-Powered\" Join"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xB1ETPZs0c1l"
   },
   "source": [
    "![Without EvaDB](without_evadb_tutorial_15.png)\n",
    "\n",
    "Consider a scenario where you have two tables - one with details about AirBnB listings in San Francisco and the other providing insights into the city's recreational parks. Our objective is to identify Airbnb listings located in neighborhoods with a high concentration of nearby parks. These datasets lack a common column for a straightforward join. The Airbnb dataset includes a 'neighborhood' column, while the parks dataset features a 'zip code' column.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "QWV-723b0c1l"
   },
   "source": [
    "![With EvaDB](with_evadb_tutorial_15.png)\n",
    "\n",
    "EvaDB steps in to address this challenge by facilitating the merging operation using language models. Below shows the key query to create a new reference table that can be joined with other tables easily."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2p4PfQZH0c1l"
   },
   "source": [
    "## Full Tutorial for using EvaDB"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3R6fdYNF0c1l"
   },
   "source": [
    "### Setup Postgres Database on Colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "iwWMlVaVaOuH",
    "outputId": "ffa0593f-74f8-4810-92d8-84d83a0f2f21"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Preconfiguring packages ...\n",
      "Selecting previously unselected package logrotate.\n",
      "(Reading database ... 120893 files and directories currently installed.)\n",
      "Preparing to unpack .../00-logrotate_3.19.0-1ubuntu1.1_amd64.deb ...\n",
      "Unpacking logrotate (3.19.0-1ubuntu1.1) ...\n",
      "Selecting previously unselected package netbase.\n",
      "Preparing to unpack .../01-netbase_6.3_all.deb ...\n",
      "Unpacking netbase (6.3) ...\n",
      "Selecting previously unselected package libcommon-sense-perl:amd64.\n",
      "Preparing to unpack .../02-libcommon-sense-perl_3.75-2build1_amd64.deb ...\n",
      "Unpacking libcommon-sense-perl:amd64 (3.75-2build1) ...\n",
      "Selecting previously unselected package libjson-perl.\n",
      "Preparing to unpack .../03-libjson-perl_4.04000-1_all.deb ...\n",
      "Unpacking libjson-perl (4.04000-1) ...\n",
      "Selecting previously unselected package libtypes-serialiser-perl.\n",
      "Preparing to unpack .../04-libtypes-serialiser-perl_1.01-1_all.deb ...\n",
      "Unpacking libtypes-serialiser-perl (1.01-1) ...\n",
      "Selecting previously unselected package libjson-xs-perl.\n",
      "Preparing to unpack .../05-libjson-xs-perl_4.030-1build3_amd64.deb ...\n",
      "Unpacking libjson-xs-perl (4.030-1build3) ...\n",
      "Selecting previously unselected package postgresql-client-common.\n",
      "Preparing to unpack .../06-postgresql-client-common_238_all.deb ...\n",
      "Unpacking postgresql-client-common (238) ...\n",
      "Selecting previously unselected package postgresql-client-14.\n",
      "Preparing to unpack .../07-postgresql-client-14_14.9-0ubuntu0.22.04.1_amd64.deb ...\n",
      "Unpacking postgresql-client-14 (14.9-0ubuntu0.22.04.1) ...\n",
      "Selecting previously unselected package ssl-cert.\n",
      "Preparing to unpack .../08-ssl-cert_1.1.2_all.deb ...\n",
      "Unpacking ssl-cert (1.1.2) ...\n",
      "Selecting previously unselected package postgresql-common.\n",
      "Preparing to unpack .../09-postgresql-common_238_all.deb ...\n",
      "Adding 'diversion of /usr/bin/pg_config to /usr/bin/pg_config.libpq-dev by postgresql-common'\n",
      "Unpacking postgresql-common (238) ...\n",
      "Selecting previously unselected package postgresql-14.\n",
      "Preparing to unpack .../10-postgresql-14_14.9-0ubuntu0.22.04.1_amd64.deb ...\n",
      "Unpacking postgresql-14 (14.9-0ubuntu0.22.04.1) ...\n",
      "Selecting previously unselected package postgresql.\n",
      "Preparing to unpack .../11-postgresql_14+238_all.deb ...\n",
      "Unpacking postgresql (14+238) ...\n",
      "Selecting previously unselected package sysstat.\n",
      "Preparing to unpack .../12-sysstat_12.5.2-2ubuntu0.2_amd64.deb ...\n",
      "Unpacking sysstat (12.5.2-2ubuntu0.2) ...\n",
      "Setting up logrotate (3.19.0-1ubuntu1.1) ...\n",
      "Created symlink /etc/systemd/system/timers.target.wants/logrotate.timer → /lib/systemd/system/logrotate.timer.\n",
      "Setting up libcommon-sense-perl:amd64 (3.75-2build1) ...\n",
      "Setting up ssl-cert (1.1.2) ...\n",
      "Setting up libtypes-serialiser-perl (1.01-1) ...\n",
      "Setting up libjson-perl (4.04000-1) ...\n",
      "Setting up netbase (6.3) ...\n",
      "Setting up sysstat (12.5.2-2ubuntu0.2) ...\n",
      "\n",
      "Creating config file /etc/default/sysstat with new version\n",
      "update-alternatives: using /usr/bin/sar.sysstat to provide /usr/bin/sar (sar) in auto mode\n",
      "Created symlink /etc/systemd/system/sysstat.service.wants/sysstat-collect.timer → /lib/systemd/system/sysstat-collect.timer.\n",
      "Created symlink /etc/systemd/system/sysstat.service.wants/sysstat-summary.timer → /lib/systemd/system/sysstat-summary.timer.\n",
      "Created symlink /etc/systemd/system/multi-user.target.wants/sysstat.service → /lib/systemd/system/sysstat.service.\n",
      "Setting up postgresql-client-common (238) ...\n",
      "Setting up libjson-xs-perl (4.030-1build3) ...\n",
      "Setting up postgresql-client-14 (14.9-0ubuntu0.22.04.1) ...\n",
      "update-alternatives: using /usr/share/postgresql/14/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode\n",
      "Setting up postgresql-common (238) ...\n",
      "Adding user postgres to group ssl-cert\n",
      "\n",
      "Creating config file /etc/postgresql-common/createcluster.conf with new version\n",
      "Building PostgreSQL dictionaries from installed myspell/hunspell packages...\n",
      "Removing obsolete dictionary files:\n",
      "Created symlink /etc/systemd/system/multi-user.target.wants/postgresql.service → /lib/systemd/system/postgresql.service.\n",
      "Setting up postgresql-14 (14.9-0ubuntu0.22.04.1) ...\n",
      "Creating new PostgreSQL cluster 14/main ...\n",
      "/usr/lib/postgresql/14/bin/initdb -D /var/lib/postgresql/14/main --auth-local peer --auth-host scram-sha-256 --no-instructions\n",
      "The files belonging to this database system will be owned by user \"postgres\".\n",
      "This user must also own the server process.\n",
      "\n",
      "The database cluster will be initialized with locale \"en_US.UTF-8\".\n",
      "The default database encoding has accordingly been set to \"UTF8\".\n",
      "The default text search configuration will be set to \"english\".\n",
      "\n",
      "Data page checksums are disabled.\n",
      "\n",
      "fixing permissions on existing directory /var/lib/postgresql/14/main ... ok\n",
      "creating subdirectories ... ok\n",
      "selecting dynamic shared memory implementation ... posix\n",
      "selecting default max_connections ... 100\n",
      "selecting default shared_buffers ... 128MB\n",
      "selecting default time zone ... Etc/UTC\n",
      "creating configuration files ... ok\n",
      "running bootstrap script ... ok\n",
      "performing post-bootstrap initialization ... ok\n",
      "syncing data to disk ... ok\n",
      "update-alternatives: using /usr/share/postgresql/14/man/man1/postmaster.1.gz to provide /usr/share/man/man1/postmaster.1.gz (postmaster.1.gz) in auto mode\n",
      "invoke-rc.d: could not determine current runlevel\n",
      "invoke-rc.d: policy-rc.d denied execution of start.\n",
      "Setting up postgresql (14+238) ...\n",
      "Processing triggers for man-db (2.10.2-1) ...\n",
      " * Starting PostgreSQL 14 database server\n",
      "   ...done.\n"
     ]
    }
   ],
   "source": [
    "!apt install -qqq postgresql\n",
    "!service postgresql start"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "mUndbObdW56m"
   },
   "source": [
    "### Create User and Database"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "VonZMyLaesil",
    "outputId": "fa9eee24-970d-4ce9-f97e-c304056bd991"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CREATE ROLE\n",
      "CREATE DATABASE\n"
     ]
    }
   ],
   "source": [
    "!sudo -u postgres psql -c \"CREATE USER eva WITH SUPERUSER PASSWORD 'password'\"\n",
    "!sudo -u postgres psql -c \"CREATE DATABASE airbnb\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OQ8JQqqaW56n"
   },
   "source": [
    "### Install EvaDB"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "i-pKJsODavE6",
    "outputId": "2ca495ff-837f-4225-dcc5-bdeefb5eb90e"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting git+https://github.com/georgia-tech-db/evadb.git@staging\n",
      "  Cloning https://github.com/georgia-tech-db/evadb.git (to revision staging) to /tmp/pip-req-build-u86ke9a7\n",
      "  Running command git clone --filter=blob:none --quiet https://github.com/georgia-tech-db/evadb.git /tmp/pip-req-build-u86ke9a7\n",
      "  Resolved https://github.com/georgia-tech-db/evadb.git to commit 80e918d07432a020891896e76f7388df690a9699\n",
      "  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
      "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
      "  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
      "Requirement already satisfied: numpy>=1.19.5 in /usr/local/lib/python3.10/dist-packages (from evadb==0.3.4+dev) (1.23.5)\n",
      "Requirement already satisfied: pandas>=1.1.5 in /usr/local/lib/python3.10/dist-packages (from evadb==0.3.4+dev) (1.5.3)\n",
      "Requirement already satisfied: sqlalchemy>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from evadb==0.3.4+dev) (2.0.20)\n",
      "Collecting sqlalchemy-utils>=0.36.6 (from evadb==0.3.4+dev)\n",
      "  Downloading SQLAlchemy_Utils-0.41.1-py3-none-any.whl (92 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m92.6/92.6 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting lark>=1.0.0 (from evadb==0.3.4+dev)\n",
      "  Downloading lark-1.1.7-py3-none-any.whl (108 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m108.9/108.9 kB\u001b[0m \u001b[31m6.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: pyyaml>=5.1 in /usr/local/lib/python3.10/dist-packages (from evadb==0.3.4+dev) (6.0.1)\n",
      "Collecting aenum>=2.2.0 (from evadb==0.3.4+dev)\n",
      "  Downloading aenum-3.1.15-py3-none-any.whl (137 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m137.6/137.6 kB\u001b[0m \u001b[31m7.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting diskcache>=5.4.0 (from evadb==0.3.4+dev)\n",
      "  Downloading diskcache-5.6.3-py3-none-any.whl (45 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m45.5/45.5 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting retry>=0.9.2 (from evadb==0.3.4+dev)\n",
      "  Downloading retry-0.9.2-py2.py3-none-any.whl (8.0 kB)\n",
      "Collecting pydantic<2 (from evadb==0.3.4+dev)\n",
      "  Downloading pydantic-1.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m14.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from evadb==0.3.4+dev) (5.9.5)\n",
      "Collecting thefuzz (from evadb==0.3.4+dev)\n",
      "  Downloading thefuzz-0.20.0-py3-none-any.whl (15 kB)\n",
      "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.5->evadb==0.3.4+dev) (2.8.2)\n",
      "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.5->evadb==0.3.4+dev) (2023.3)\n",
      "Requirement already satisfied: typing-extensions>=4.2.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<2->evadb==0.3.4+dev) (4.7.1)\n",
      "Requirement already satisfied: decorator>=3.4.2 in /usr/local/lib/python3.10/dist-packages (from retry>=0.9.2->evadb==0.3.4+dev) (4.4.2)\n",
      "Collecting py<2.0.0,>=1.4.26 (from retry>=0.9.2->evadb==0.3.4+dev)\n",
      "  Downloading py-1.11.0-py2.py3-none-any.whl (98 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m98.7/98.7 kB\u001b[0m \u001b[31m9.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from sqlalchemy>=2.0.0->evadb==0.3.4+dev) (2.0.2)\n",
      "Collecting rapidfuzz<4.0.0,>=3.0.0 (from thefuzz->evadb==0.3.4+dev)\n",
      "  Downloading rapidfuzz-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.1/3.1 MB\u001b[0m \u001b[31m26.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.1->pandas>=1.1.5->evadb==0.3.4+dev) (1.16.0)\n",
      "Building wheels for collected packages: evadb\n",
      "  Building wheel for evadb (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
      "  Created wheel for evadb: filename=evadb-0.3.4+dev-py3-none-any.whl size=507878 sha256=b7997acf2987cbb00d54979bbfed4cc1aa23606444b5a6c9bd10f35e8410640f\n",
      "  Stored in directory: /tmp/pip-ephem-wheel-cache-1ap99wpq/wheels/b3/a0/ff/986be8daa3d585d35383e2b0a9b2cb3052c36ea6625ce2ff1b\n",
      "Successfully built evadb\n",
      "Installing collected packages: aenum, rapidfuzz, pydantic, py, lark, diskcache, thefuzz, sqlalchemy-utils, retry, evadb\n",
      "  Attempting uninstall: pydantic\n",
      "    Found existing installation: pydantic 2.2.1\n",
      "    Uninstalling pydantic-2.2.1:\n",
      "      Successfully uninstalled pydantic-2.2.1\n",
      "Successfully installed aenum-3.1.15 diskcache-5.6.3 evadb-0.3.4+dev lark-1.1.7 py-1.11.0 pydantic-1.10.12 rapidfuzz-3.2.0 retry-0.9.2 sqlalchemy-utils-0.41.1 thefuzz-0.20.0\n",
      "Requirement already satisfied: psycopg2 in /usr/local/lib/python3.10/dist-packages (2.9.7)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Downloading: \"http://ml.cs.tsinghua.edu.cn/~chenxi/pytorch-models/mnist-b07bb66b.pth\" to /root/.cache/torch/hub/checkpoints/mnist-b07bb66b.pth\n",
      "100%|██████████| 1.03M/1.03M [00:01<00:00, 880kB/s]\n",
      "Downloading: \"https://download.pytorch.org/models/fasterrcnn_resnet50_fpn_coco-258fb6c6.pth\" to /root/.cache/torch/hub/checkpoints/fasterrcnn_resnet50_fpn_coco-258fb6c6.pth\n"
     ]
    }
   ],
   "source": [
    "%pip install --quiet \"evadb[document]\"\n",
    "%pip install psycopg2\n",
    "\n",
    "import evadb\n",
    "cursor = evadb.connect().cursor()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "id": "YT8nVVKoaC_D"
   },
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "from IPython.core.display import display, HTML\n",
    "def pretty_print(df):\n",
    "    return display(HTML( df.to_html().replace(\"\\\\n\",\"<br>\")))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nnXs1OxpW56o"
   },
   "source": [
    "### Create Data Source in EvaDB\n",
    "We use data source to connect EvaDB directly to underlying database systems like Postgres."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 81
    },
    "id": "PkbSv2gKc5Nd",
    "outputId": "e97b8cff-4d3a-43ea-fcef-9893584b2e82"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "  <div id=\"df-b8afa90e-aedd-48f6-9852-973b4e966cca\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>The database pg_db has been successfully created.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-b8afa90e-aedd-48f6-9852-973b4e966cca')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-b8afa90e-aedd-48f6-9852-973b4e966cca button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-b8afa90e-aedd-48f6-9852-973b4e966cca');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "    </div>\n",
       "  </div>\n"
      ],
      "text/plain": [
       "                                                   0\n",
       "0  The database pg_db has been successfully created."
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "params = {\n",
    "    \"user\": \"eva\",\n",
    "    \"password\": \"password\",\n",
    "    \"host\": \"localhost\",\n",
    "    \"port\": \"5432\",\n",
    "    \"database\": \"airbnb\",\n",
    "}\n",
    "query = f\"CREATE DATABASE pg_db WITH ENGINE = 'postgres', PARAMETERS = {params};\"\n",
    "cursor.query(query).df()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ew9wsQUwW56p"
   },
   "source": [
    "## Loading the Datasets\n",
    "\n",
    "Our next step involves loading the dataset CSVs into our PostgreSQL database:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 652
    },
    "id": "tt1MB5CrtYHy",
    "outputId": "ae983816-e949-473e-e9b1-3248ef047925"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--2023-09-06 04:11:19--  https://gist.github.com/gaurav274/2cb7ee709bf8900fc439fc2cc3f9edb6/raw/sf_recreational_parks.csv\n",
      "Resolving gist.github.com (gist.github.com)... 140.82.112.3\n",
      "Connecting to gist.github.com (gist.github.com)|140.82.112.3|:443... connected.\n",
      "HTTP request sent, awaiting response... 301 Moved Permanently\n",
      "Location: https://gist.githubusercontent.com/gaurav274/2cb7ee709bf8900fc439fc2cc3f9edb6/raw/sf_recreational_parks.csv [following]\n",
      "--2023-09-06 04:11:19--  https://gist.githubusercontent.com/gaurav274/2cb7ee709bf8900fc439fc2cc3f9edb6/raw/sf_recreational_parks.csv\n",
      "Resolving gist.githubusercontent.com (gist.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n",
      "Connecting to gist.githubusercontent.com (gist.githubusercontent.com)|185.199.108.133|:443... connected.\n",
      "HTTP request sent, awaiting response... 200 OK\n",
      "Length: 11645 (11K) [text/plain]\n",
      "Saving to: ‘/content/sf_recreational_parks.csv’\n",
      "\n",
      "/content/sf_recreat 100%[===================>]  11.37K  --.-KB/s    in 0s      \n",
      "\n",
      "2023-09-06 04:11:20 (73.4 MB/s) - ‘/content/sf_recreational_parks.csv’ saved [11645/11645]\n",
      "\n",
      "--2023-09-06 04:11:20--  https://gist.github.com/gaurav274/9444867ed4b70af16c1863915c12dfe5/raw/airbnb_listings.csv\n",
      "Resolving gist.github.com (gist.github.com)... 140.82.112.3\n",
      "Connecting to gist.github.com (gist.github.com)|140.82.112.3|:443... connected.\n",
      "HTTP request sent, awaiting response... 301 Moved Permanently\n",
      "Location: https://gist.githubusercontent.com/gaurav274/9444867ed4b70af16c1863915c12dfe5/raw/airbnb_listings.csv [following]\n",
      "--2023-09-06 04:11:20--  https://gist.githubusercontent.com/gaurav274/9444867ed4b70af16c1863915c12dfe5/raw/airbnb_listings.csv\n",
      "Resolving gist.githubusercontent.com (gist.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n",
      "Connecting to gist.githubusercontent.com (gist.githubusercontent.com)|185.199.108.133|:443... connected.\n",
      "HTTP request sent, awaiting response... 200 OK\n",
      "Length: 1544377 (1.5M) [text/plain]\n",
      "Saving to: ‘/content/airbnb_listings.csv’\n",
      "\n",
      "/content/airbnb_lis 100%[===================>]   1.47M  --.-KB/s    in 0.06s   \n",
      "\n",
      "2023-09-06 04:11:20 (26.1 MB/s) - ‘/content/airbnb_listings.csv’ saved [1544377/1544377]\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "  <div id=\"df-153145d9-7184-4683-8b68-b90a5028c02c\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>status</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>success</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-153145d9-7184-4683-8b68-b90a5028c02c')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-153145d9-7184-4683-8b68-b90a5028c02c button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-153145d9-7184-4683-8b68-b90a5028c02c');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "    </div>\n",
       "  </div>\n"
      ],
      "text/plain": [
       "    status\n",
       "0  success"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Fetch the datasets\n",
    "\n",
    "!mkdir -p content\n",
    "\n",
    "!wget -nc -O /content/sf_recreational_parks.csv https://gist.github.com/gaurav274/2cb7ee709bf8900fc439fc2cc3f9edb6/raw/sf_recreational_parks.csv\n",
    "\n",
    "!wget -nc -O /content/airbnb_listings.csv https://gist.github.com/gaurav274/9444867ed4b70af16c1863915c12dfe5/raw/airbnb_listings.csv\n",
    "\n",
    "# Create the airbnb_listing table\n",
    "cursor.query(\"\"\"\n",
    "          USE pg_db{\n",
    "CREATE TABLE IF NOT EXISTS airbnb_listing (id INT, name VARCHAR(100), summary VARCHAR(1000), neighbourhood VARCHAR(100))}\"\"\").df()\n",
    "\n",
    "# Load data into the airbnb_listing table\n",
    "cursor.query(\"\"\"\n",
    "USE pg_db {\n",
    "  COPY airbnb_listing(id, name, summary, neighbourhood)\n",
    "  FROM '/content/airbnb_listings.csv'\n",
    "  DELIMITER ',' CSV HEADER}\n",
    "\"\"\").df()\n",
    "\n",
    "# Create the recreational_park_dataset table\n",
    "cursor.query(\"\"\"\n",
    "          USE pg_db{\n",
    "CREATE TABLE IF NOT EXISTS recreational_park_dataset (parkName VARCHAR(100), ParkType VARCHAR(100), Zipcode INT)}\"\"\").df()\n",
    "\n",
    "\n",
    "# Load data into the recreational_park_dataset table\n",
    "cursor.query(\"\"\"\n",
    "USE pg_db {\n",
    "  COPY recreational_park_dataset(parkName, ParkType, Zipcode)\n",
    "  FROM '/content/sf_recreational_parks.csv'\n",
    "  DELIMITER ',' CSV HEADER}\n",
    "\"\"\").df()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "PblBKYOI0c1n"
   },
   "source": [
    "### Use AI-Powered Queries in EvaDB\n",
    "\n",
    "EvaDB bridges the semantic gap between the two tables using OpenAI's LLM model. We create a new 'reference' table to map San Francisco neighborhoods to their corresponding zip codes. First, we retrieve all distinct neighborhoods from our Airbnb listings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 107
    },
    "id": "BJnQCg7RbImb",
    "outputId": "e9bc3230-efb4-4cf8-e3fe-db7080017fe7"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.google.colaboratory.intrinsic+json": {
       "type": "string"
      },
      "text/plain": [
       "\"Return the San Francisco neighbourhood name when provided with a zipcode.  The possible neighborhoods are: Civic Center, Duboce Triangle, Forest Hill, Tenderloin, SoMa, Outer Sunset, Financial District, Portola, Excelsior, Mission District, The Castro, Dogpatch, Hayes Valley, North Beach, Fisherman's Wharf, Richmond District, Haight-Ashbury, Union Square, Chinatown, Telegraph Hill, Sea Cliff, Potrero Hill, Oceanview, Downtown, Presidio Heights, South Beach, Balboa Terrace, Alamo Square, Mission Bay, Cole Valley, Twin Peaks, Bernal Heights, Crocker Amazon, Pacific Heights, Presidio, Parkside, Glen Park, West Portal, Sunnyside, Lower Haight, Lakeshore, Ingleside, Visitacion Valley, Noe Valley, Nob Hill, Mission Terrace, Bayview, Diamond Heights, Western Addition/NOPA, Inner Sunset, Marina, Cow Hollow, Russian Hill. The response should an item from the provided list. Do not add any more words.\""
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "neighbourhoods = cursor.query(\"\"\"\n",
    "USE pg_db {\n",
    "  SELECT distinct(airbnb_listing.neighbourhood) from airbnb_listing}\n",
    "\"\"\").df()\n",
    "\n",
    "neighbourhoods_str = ', '.join(neighbourhoods['neighbourhood'])\n",
    "\n",
    "prompt = f\"Return the San Francisco neighbourhood name when provided with a zipcode.  The possible neighborhoods are: {neighbourhoods_str}. The response should an item from the provided list. Do not add any more words.\"\n",
    "prompt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Fy87awpj0c1o"
   },
   "source": [
    "Next, we use LLM to associate a zip code with each neighborhood."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 424
    },
    "id": "K3AQssRB0c1o",
    "outputId": "44fdca12-6cf4-4d94-efe9-fef9c10dfd06"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "  <div id=\"df-7cde495c-1b96-4696-b66e-69f16a1c1f0b\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>reference_table2._row_id</th>\n",
       "      <th>reference_table2.parkname</th>\n",
       "      <th>reference_table2.parktype</th>\n",
       "      <th>reference_table2.response</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>10TH AVE/CLEMENT MINI PARK</td>\n",
       "      <td>Mini Park</td>\n",
       "      <td>Inner Sunset</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>15TH AVENUE STEPS</td>\n",
       "      <td>Mini Park</td>\n",
       "      <td>Outer Sunset</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>24TH/YORK MINI PARK</td>\n",
       "      <td>Mini Park</td>\n",
       "      <td>Mission District</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>29TH/DIAMOND OPEN SPACE</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Noe Valley</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>ADAM ROGERS PARK</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Bayview</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>218</th>\n",
       "      <td>219</td>\n",
       "      <td>WILLIE WOO WOO WONG PLAYGROUND</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Nob Hill</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>219</th>\n",
       "      <td>220</td>\n",
       "      <td>WOH HEI YUEN PARK</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>North Beach</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>220</th>\n",
       "      <td>221</td>\n",
       "      <td>Wolfe Lane Community Garden</td>\n",
       "      <td>Community Garden</td>\n",
       "      <td>Mission District</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>221</th>\n",
       "      <td>222</td>\n",
       "      <td>YACHT HARBOR AND MARINA GREEN</td>\n",
       "      <td>Regional Park</td>\n",
       "      <td>Marina</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>222</th>\n",
       "      <td>223</td>\n",
       "      <td>YOUNGBLOOD COLEMAN PLAYGROUND</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Bayview</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>223 rows × 4 columns</p>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-7cde495c-1b96-4696-b66e-69f16a1c1f0b')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-7cde495c-1b96-4696-b66e-69f16a1c1f0b button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-7cde495c-1b96-4696-b66e-69f16a1c1f0b');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-f689de00-e4e1-4603-bcf7-3393180e0be3\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-f689de00-e4e1-4603-bcf7-3393180e0be3')\"\n",
       "            title=\"Suggest charts.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-f689de00-e4e1-4603-bcf7-3393180e0be3 button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "    </div>\n",
       "  </div>\n"
      ],
      "text/plain": [
       "     reference_table2._row_id       reference_table2.parkname  \\\n",
       "0                           1      10TH AVE/CLEMENT MINI PARK   \n",
       "1                           2               15TH AVENUE STEPS   \n",
       "2                           3             24TH/YORK MINI PARK   \n",
       "3                           4         29TH/DIAMOND OPEN SPACE   \n",
       "4                           5                ADAM ROGERS PARK   \n",
       "..                        ...                             ...   \n",
       "218                       219  WILLIE WOO WOO WONG PLAYGROUND   \n",
       "219                       220               WOH HEI YUEN PARK   \n",
       "220                       221     Wolfe Lane Community Garden   \n",
       "221                       222   YACHT HARBOR AND MARINA GREEN   \n",
       "222                       223   YOUNGBLOOD COLEMAN PLAYGROUND   \n",
       "\n",
       "           reference_table2.parktype reference_table2.response  \n",
       "0                          Mini Park              Inner Sunset  \n",
       "1                          Mini Park              Outer Sunset  \n",
       "2                          Mini Park          Mission District  \n",
       "3    Neighborhood Park or Playground                Noe Valley  \n",
       "4    Neighborhood Park or Playground                   Bayview  \n",
       "..                               ...                       ...  \n",
       "218  Neighborhood Park or Playground                  Nob Hill  \n",
       "219  Neighborhood Park or Playground               North Beach  \n",
       "220                 Community Garden          Mission District  \n",
       "221                    Regional Park                    Marina  \n",
       "222  Neighborhood Park or Playground                   Bayview  \n",
       "\n",
       "[223 rows x 4 columns]"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "os.environ[\"OPENAI_KEY\"] = \"sk-...\"\n",
    "\n",
    "cursor.query(f\"\"\"CREATE TABLE reference_table AS SELECT parkname, parktype, ChatGPT(\"{prompt}\",zipcode) FROM pg_db.recreational_park_dataset\"\"\").df()\n",
    "cursor.query(\"Select * from reference_table;\").df()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0-ryz6330c1o"
   },
   "source": [
    "### Deriving insights using EvaDB\n",
    "With our reference table prepared, it's time for the crucial step. We will now combine the reference table with the Airbnb listings to gain valuable insights into properties located nearest to the city's parks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 652
    },
    "id": "wtk_Iuai0c1o",
    "outputId": "91a818a6-2f8b-4b33-c29a-d7a57276b818"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "  <div id=\"df-7220b734-8945-4e06-b3c5-3b5e6893a0aa\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>airbnb_listing.id</th>\n",
       "      <th>airbnb_listing.name</th>\n",
       "      <th>airbnb_listing.summary</th>\n",
       "      <th>airbnb_listing.neighbourhood</th>\n",
       "      <th>reference_table2._row_id</th>\n",
       "      <th>reference_table2.parkname</th>\n",
       "      <th>reference_table2.parktype</th>\n",
       "      <th>reference_table2.response</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>110825</td>\n",
       "      <td>Charming Cottage with Bay View</td>\n",
       "      <td>None</td>\n",
       "      <td>Bayview</td>\n",
       "      <td>5</td>\n",
       "      <td>ADAM ROGERS PARK</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Bayview</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>522273</td>\n",
       "      <td>Amazing Private Room w/View in Beautiful SF Flat</td>\n",
       "      <td>Large private room w/ amazing downtown views. ...</td>\n",
       "      <td>Bayview</td>\n",
       "      <td>5</td>\n",
       "      <td>ADAM ROGERS PARK</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Bayview</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>631735</td>\n",
       "      <td>Comfy Room in SF Victorian house</td>\n",
       "      <td>The room we offer is in our Queen Ann Victoria...</td>\n",
       "      <td>Bayview</td>\n",
       "      <td>5</td>\n",
       "      <td>ADAM ROGERS PARK</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Bayview</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>654279</td>\n",
       "      <td>Quiet Room in Our Friendly Home</td>\n",
       "      <td>Private room for up to two guests in our home ...</td>\n",
       "      <td>Bayview</td>\n",
       "      <td>5</td>\n",
       "      <td>ADAM ROGERS PARK</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Bayview</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>782126</td>\n",
       "      <td>Great Rm In A Happy Household S.F.</td>\n",
       "      <td>This is a lovely room in a funky cool househol...</td>\n",
       "      <td>Bayview</td>\n",
       "      <td>5</td>\n",
       "      <td>ADAM ROGERS PARK</td>\n",
       "      <td>Neighborhood Park or Playground</td>\n",
       "      <td>Bayview</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37437</th>\n",
       "      <td>21189031</td>\n",
       "      <td>Sunny Studio Apartment with Private Deck.</td>\n",
       "      <td>Noe Valley Studio - Prime Location -  2 blocks...</td>\n",
       "      <td>Noe Valley</td>\n",
       "      <td>218</td>\n",
       "      <td>White Crane Springs Community Garden</td>\n",
       "      <td>Community Garden</td>\n",
       "      <td>Noe Valley</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37438</th>\n",
       "      <td>21398528</td>\n",
       "      <td>Iconic Victorian Architecture with City Views</td>\n",
       "      <td>Relish staying in this Victorian San Francisco...</td>\n",
       "      <td>Noe Valley</td>\n",
       "      <td>218</td>\n",
       "      <td>White Crane Springs Community Garden</td>\n",
       "      <td>Community Garden</td>\n",
       "      <td>Noe Valley</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37439</th>\n",
       "      <td>21298312</td>\n",
       "      <td>Serene Victorian with Views in Noe Valley</td>\n",
       "      <td>Striking potted plants tower above a seafoam g...</td>\n",
       "      <td>Noe Valley</td>\n",
       "      <td>218</td>\n",
       "      <td>White Crane Springs Community Garden</td>\n",
       "      <td>Community Garden</td>\n",
       "      <td>Noe Valley</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37440</th>\n",
       "      <td>21345382</td>\n",
       "      <td>Light-filled, spacious family home with parking</td>\n",
       "      <td>Beautiful, spacious and light-filled house, wi...</td>\n",
       "      <td>Noe Valley</td>\n",
       "      <td>218</td>\n",
       "      <td>White Crane Springs Community Garden</td>\n",
       "      <td>Community Garden</td>\n",
       "      <td>Noe Valley</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37441</th>\n",
       "      <td>21399171</td>\n",
       "      <td>New! Private ensuite, loft ceilings, heated fl...</td>\n",
       "      <td>Welcome to our home minutes away from the cute...</td>\n",
       "      <td>Noe Valley</td>\n",
       "      <td>218</td>\n",
       "      <td>White Crane Springs Community Garden</td>\n",
       "      <td>Community Garden</td>\n",
       "      <td>Noe Valley</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>37442 rows × 8 columns</p>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-7220b734-8945-4e06-b3c5-3b5e6893a0aa')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-7220b734-8945-4e06-b3c5-3b5e6893a0aa button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-7220b734-8945-4e06-b3c5-3b5e6893a0aa');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-ee7db46d-5a7d-4ce7-a438-687ed09a7e53\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-ee7db46d-5a7d-4ce7-a438-687ed09a7e53')\"\n",
       "            title=\"Suggest charts.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-ee7db46d-5a7d-4ce7-a438-687ed09a7e53 button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "    </div>\n",
       "  </div>\n"
      ],
      "text/plain": [
       "       airbnb_listing.id                                airbnb_listing.name  \\\n",
       "0                 110825                     Charming Cottage with Bay View   \n",
       "1                 522273   Amazing Private Room w/View in Beautiful SF Flat   \n",
       "2                 631735                   Comfy Room in SF Victorian house   \n",
       "3                 654279                    Quiet Room in Our Friendly Home   \n",
       "4                 782126                 Great Rm In A Happy Household S.F.   \n",
       "...                  ...                                                ...   \n",
       "37437           21189031          Sunny Studio Apartment with Private Deck.   \n",
       "37438           21398528      Iconic Victorian Architecture with City Views   \n",
       "37439           21298312          Serene Victorian with Views in Noe Valley   \n",
       "37440           21345382    Light-filled, spacious family home with parking   \n",
       "37441           21399171  New! Private ensuite, loft ceilings, heated fl...   \n",
       "\n",
       "                                  airbnb_listing.summary  \\\n",
       "0                                                   None   \n",
       "1      Large private room w/ amazing downtown views. ...   \n",
       "2      The room we offer is in our Queen Ann Victoria...   \n",
       "3      Private room for up to two guests in our home ...   \n",
       "4      This is a lovely room in a funky cool househol...   \n",
       "...                                                  ...   \n",
       "37437  Noe Valley Studio - Prime Location -  2 blocks...   \n",
       "37438  Relish staying in this Victorian San Francisco...   \n",
       "37439  Striking potted plants tower above a seafoam g...   \n",
       "37440  Beautiful, spacious and light-filled house, wi...   \n",
       "37441  Welcome to our home minutes away from the cute...   \n",
       "\n",
       "      airbnb_listing.neighbourhood  reference_table2._row_id  \\\n",
       "0                          Bayview                         5   \n",
       "1                          Bayview                         5   \n",
       "2                          Bayview                         5   \n",
       "3                          Bayview                         5   \n",
       "4                          Bayview                         5   \n",
       "...                            ...                       ...   \n",
       "37437                   Noe Valley                       218   \n",
       "37438                   Noe Valley                       218   \n",
       "37439                   Noe Valley                       218   \n",
       "37440                   Noe Valley                       218   \n",
       "37441                   Noe Valley                       218   \n",
       "\n",
       "                  reference_table2.parkname        reference_table2.parktype  \\\n",
       "0                          ADAM ROGERS PARK  Neighborhood Park or Playground   \n",
       "1                          ADAM ROGERS PARK  Neighborhood Park or Playground   \n",
       "2                          ADAM ROGERS PARK  Neighborhood Park or Playground   \n",
       "3                          ADAM ROGERS PARK  Neighborhood Park or Playground   \n",
       "4                          ADAM ROGERS PARK  Neighborhood Park or Playground   \n",
       "...                                     ...                              ...   \n",
       "37437  White Crane Springs Community Garden                 Community Garden   \n",
       "37438  White Crane Springs Community Garden                 Community Garden   \n",
       "37439  White Crane Springs Community Garden                 Community Garden   \n",
       "37440  White Crane Springs Community Garden                 Community Garden   \n",
       "37441  White Crane Springs Community Garden                 Community Garden   \n",
       "\n",
       "      reference_table2.response  \n",
       "0                       Bayview  \n",
       "1                       Bayview  \n",
       "2                       Bayview  \n",
       "3                       Bayview  \n",
       "4                       Bayview  \n",
       "...                         ...  \n",
       "37437                Noe Valley  \n",
       "37438                Noe Valley  \n",
       "37439                Noe Valley  \n",
       "37440                Noe Valley  \n",
       "37441                Noe Valley  \n",
       "\n",
       "[37442 rows x 8 columns]"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "aggregated_table = cursor.query(\"select * from pg_db.airbnb_listing join reference_table ON airbnb_listing.neighbourhood = reference_table.response;\").df()\n",
    "aggregated_table"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "IabKOtCB0c1o"
   },
   "source": [
    "This aggregated table opens the door to various analytical possibilities. Below, we present a chart illustrating the number of parks in each neighborhood. This data can inform decisions when recommending potential Airbnb locations for individuals who enjoy staying in proximity to recreational parks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 407
    },
    "id": "k8MDRDzG0c1o",
    "outputId": "9104a500-0f0c-433e-ec62-fcbd6be7a6ba"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot(df):\n",
    "    import matplotlib.pyplot as plt\n",
    "    grouped = df.groupby(df.columns[3]).size().reset_index(name='count')\n",
    "\n",
    "    # Plotting\n",
    "    fig, ax = plt.subplots(figsize=(6, 4))\n",
    "    grouped.plot(kind='bar', x=grouped.columns[0], y=grouped.columns[1], ax=ax, legend=False, color='#ed7d32', width=0.6)\n",
    "\n",
    "    plt.title('Concentration of recreational parks', fontsize=18)\n",
    "    plt.xlabel('SF neighbourhood', fontsize=14)\n",
    "    plt.ylabel('Park count', fontsize=14)\n",
    "\n",
    "\n",
    "    # Set the font size for tick labels\n",
    "    plt.xticks(rotation=75, fontsize=8)\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "\n",
    "plot(aggregated_table)"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
